/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package IpChat_For_Testing;

/**
 *
 * @author lubinchen
 */
import java.net.*;
import java.io.*;

import java.util.*;

public class ChatServer implements Runnable
{  private ChatServerThread clients[] = new ChatServerThread[20];
   private ServerSocket server = null;
   private Thread       thread = null;
   private Integer clientCount = 0;
   public  IpChat_Constructor callthisobject=null;
   public  static Integer ownTeamNumber=new Integer(-1) ;
   private String MyOwnIP=null;
   public  String MyOwnName=null;

  

   public ChatServer(int port, IpChat_Constructor call)
   {

     try
      {  System.out.println("Binding to port " + port + ", please wait  ...");
         server = new ServerSocket(port);
         System.out.println("Your server has started: " + server);
         callthisobject=call;
      
         try{
	      InetAddress ownIP=InetAddress.getLocalHost();
              MyOwnIP=ownIP.getHostAddress();
	    }catch (Exception e){
	      System.out.println("Exception caught "+e.getMessage());
	    }

         for (int HTI=0; HTI<callthisobject.received_ht_al.size(); HTI++)
            if (MyOwnIP.equals(callthisobject.received_ht_al.get(HTI).get("ip"))  ){
                ownTeamNumber=(Integer) callthisobject.received_ht_al.get(HTI).get("team") ;
                MyOwnName=(String)callthisobject.received_ht_al.get(HTI).get("username") ;

             }
         System.out.println("@ChatServer. My Own Ip= "+MyOwnIP+". My Own Team= team is "+ownTeamNumber+" .My own name is "+MyOwnName);


         start();

      }
      catch(IOException ioe)
      {  System.out.println("Can not bind to port: " + port + ": " + ioe.getMessage()); }

   }





   public void run()
   {  while (thread != null)
      {  try
         { // System.out.println("Your server is now waiting for a connection request from a client ...");
            addThread(server.accept());
         }
         catch(IOException ioe)
         {  System.out.println("Server accept error: " + ioe); stop(); }
      }
   }




    public void start()
   {  if (thread == null)
      {  thread = new Thread(this);
         thread.start();
      }
   }




   public void stop()
   {  if (thread != null)
      {  thread.stop();
         thread = null;
      }
   }




   private int findClient(int ID)
   {  for (int i = 0; i < clientCount; i++)
         if (clients[i].getID() == ID)
            return i;
      return -1;
   }



   

// send out to screen to display
    public synchronized void handle(String input, String Name, String  clientIP)
   {

       //decode the input string
       IpChat_Main.has_new_text=false;
       String firstCharacter=null;
       System.out.println("@ChatServer. Full massage received from "+Name+" is: "+input);
       String ActualMsg=input.substring(36,input.length()-1);
       firstCharacter=ActualMsg.substring(0,1);
      
       ActualMsg=Name.concat(": ").concat(  ActualMsg.substring(1,ActualMsg.length())  );

       System.out.println("@ChatServer. New text received.   firstCharacter= "+firstCharacter );
       System.out.println("@ChatServer.                           ActualMsg= "+ActualMsg);

        // if this is a team message and i am in his team, display read
          if (firstCharacter.equals("T"))
          {
              System.out.println("@ChatServer.This is a Team private message from "+Name);
              
                  for (int HTI=0; HTI<callthisobject.received_ht_al.size(); HTI++)
                    if ( clientIP.equals(callthisobject.received_ht_al.get(HTI).get("ip"))  )
                     {
                      
                        Integer clientTeamNumber= new Integer((Integer) callthisobject.received_ht_al.get(HTI).get("team") );
                        System.out.println("@ChatServer. My ownTeamnumber= "+ownTeamNumber +". TeamNum of client name  "+ Name + " that sent this new text is "+ clientTeamNumber);
                        if(ownTeamNumber.compareTo(clientTeamNumber)==0)
                        {

                            //clients[i].send(Packet_msg);
                            IpChat_Main.gui.addchatH(ActualMsg,"Red");
                            System.out.println("ownTeamNumber.compareTo(clientTeamNumber)= "+ ownTeamNumber.compareTo(clientTeamNumber));
                            System.out.println("@ChatServer.New message displayed as red"+ActualMsg);
                            //System.out.println("@ChatServer. actuall to Team message sent was: "+ Packet_msg);
                         }
                        else{
                            System.out.println("ownTeamNumber.compareTo(clientTeamNumber)= "+ ownTeamNumber.compareTo(clientTeamNumber));
                            System.out.println("@ChatServer.New message Not shown.");
                        }
                        break;

                      }
          }

          // else just display blue
          else
             IpChat_Main.gui.addchatH(ActualMsg,"Blue");         
     }





   public synchronized void remove(int ID)
   {  int pos = findClient(ID);

      if (pos >= 0)
      {  ChatServerThread toTerminate = clients[pos];
         System.out.println("@ChatServer.remove(): Removing server thread of port no. " + ID + " at client list index= " + pos);
         
         //new code
            for (int i=0; i< callthisobject.received_ht_al.size();i++)
            if( callthisobject.received_ht_al.get(i).get("username")==clients[pos].name )
            {
              callthisobject.received_ht_al.get(i).remove("connected");
              Boolean connectedd=false;
              callthisobject.received_ht_al.get(i).put("connected",connectedd);
              System.out.println("@ChatServer.remove(): Client Thread for "+ clients[pos].name+ " is "+ connectedd  );
              
             for (int y=0; y<IpChat_Constructor.clientCount;y++)
             {
                 if (IpChat_Constructor.clients[y].clientname == null ? clients[pos].name == null : callthisobject.clients[y].clientname.equals(clients[pos].name))
                 {
                     if (y < IpChat_Constructor.clientCount-1)
                     for (int r = y+1; r < IpChat_Constructor.clientCount; r++)
                        IpChat_Constructor.clients[r-1] = IpChat_Constructor.clients[r];
                     IpChat_Constructor.clientCount--;
                 }
                 break;
             }

            }



         if (pos < clientCount-1)
            for (int i = pos+1; i < clientCount; i++)
               clients[i-1] = clients[i];
         clientCount--;
         System.out.println("\n");
         System.out.println("@ChatServer.Connected Client List is updated to: Clients[] has ");
         for (int y=0; y<IpChat_Constructor.clientCount;y++)
             {
                System.out.println("client name= "+IpChat_Constructor.clients[y].clientname);
             }


         System.out.println("\n");
         System.out.println("@ChatServer.Server List List is updated to: ");
         for (int y=0; y<clientCount;y++)
             {
                System.out.println("Server Thread for= "+clients[y].name);
             }

         System.out.println("\n");


         // end of new code


         try
         {  toTerminate.close(); }
         catch(IOException ioe)
         {  System.out.println("@ChatServer.remove(): Error closing thread because " + ioe); }
         toTerminate.stop(); }
   }



   // the original addthread
   private void addThread(Socket socket)
   {

       if (clientCount < clients.length)
      {  System.out.println("@ChatServer.AddThread: Client accepted: " + socket);

         String name="unregistered";
         String socketIP=socket.getInetAddress().getHostAddress();

          for(int i=0;i<callthisobject.received_ht_al.size();i++)
            if(callthisobject.received_ht_al.get(i).get("ip")==null ? socketIP==null : callthisobject.received_ht_al.get(i).get("ip").equals(socketIP) )
            {   //if ((Boolean)callthisobject.received_ht_al.get(i).get("connected")== false)
                    name=(String)callthisobject.received_ht_al.get(i).get("username");
                    System.out.println("@ChatServer. AddThread.  Request received from "+name);
                    break;
              }



         clients[clientCount] = new ChatServerThread(this, socket, name);
         try
         {  clients[clientCount].open();
            clients[clientCount].start();
            clientCount++; }
         catch(IOException ioe)
         {  System.out.println("@ChatServer.AddThread: Error opening thread: " + ioe); } }
          else
         System.out.println("@ChatServer.AddThread: Client refused: maximum " + clients.length + " reached.");

       System.out.println("@ChatServer.AddThread: clientCount= "+clientCount);

       // new code added
       //check if the newly added server thread has a working client thread
       callthisobject.checkunconnected();


   }

}
